package com.monika.main.system.util.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Set;

/**
 * Author whh
 * Date 2023/05/11/ 23:33
 * <p></p>
 */
public abstract class ProxyInvocationHandler<T> implements InvocationHandler {


    T target;

    Set<String> excludeMethods;


    /**
     * @param target         被代理对象
     * @param excludeMethods 非代理方法
     */
    public ProxyInvocationHandler(T target, Set<String> excludeMethods) {
        this.target = target;
        this.excludeMethods = excludeMethods;
    }


    /**
     * 前置动作
     *
     * @param target
     * @param method
     * @param args
     */
    public abstract void before(T target, Method method, Object[] args);


    /**
     * 后置动作
     *
     * @param target
     * @param method
     * @param args
     * @param result
     */
    public abstract void after(T target, Method method, Object[] args, Object result);


    /**
     * 异常处理
     *
     * @param target
     * @param method
     * @param args
     * @param t
     */
    public abstract void exception(T target, Method method, Object[] args, Throwable t);


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        if (excludeMethods != null && excludeMethods.contains(method.getName())) {
            return method.invoke(target, args);
        }
        try {
            before(target, method, args);
            Object result = method.invoke(target, args);
            after(target, method, args, result);
            return result;
        } catch (Throwable t) {
            exception(target, method, args, t);
            throw t;
        }
    }
}
